#include "viewmodel_factory.h"
#include "viewmodels/map_view_model.h"
#include "viewmodels/dashboard_view_model.h"
#include "viewmodels/vehicle_view_model.h"
#include "viewmodels/task_view_model.h"
#include "viewmodels/resource_view_model.h"
#include "viewmodels/simulator_view_model.h"
#include "viewmodels/log_view_model.h"
#include "infrastructure/di/servicecontainer.h"
#include "application/map/map_application_service.h"
#include "application/vehicle/vehicle_service.h"
#include "application/task/task_service.h"
#include "application/simulation/simulation_service.h"
#include <QDebug>

namespace presentation {
namespace factories {

ViewModelFactory::ViewModelFactory(std::shared_ptr<infrastructure::ServiceContainer> serviceContainer, 
                                 QObject* parent)
    : QObject(parent)
    , m_serviceContainer(serviceContainer)
{
    qDebug() << "ViewModelFactory: Created with service container" 
             << (m_serviceContainer ? "available" : "null");
}

QObject* ViewModelFactory::createMapViewModel(QObject* parent)
{
    if (!m_serviceContainer) {
        qWarning() << "ViewModelFactory: No service container available, creating demo MapViewModel";
        auto viewModel = new MapViewModel(parent);
        logViewModelCreation("MapViewModel", true, "Demo mode - no service container");
        return viewModel;
    }

    try {
        // 从服务容器解析MapApplicationService
        auto mapAppService = m_serviceContainer->resolve<application::MapApplicationService>();
        if (mapAppService) {
            qDebug() << "ViewModelFactory: Successfully resolved MapApplicationService, creating injected MapViewModel";
            auto viewModel = new MapViewModel(mapAppService.get(), parent);
            logViewModelCreation("MapViewModel", true);
            emit viewModelCreated("MapViewModel");
            return viewModel;
        } else {
            qWarning() << "ViewModelFactory: Failed to resolve MapApplicationService, creating demo MapViewModel";
            auto viewModel = new MapViewModel(parent);
            logViewModelCreation("MapViewModel", true, "Demo mode - service resolution failed");
            return viewModel;
        }
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception resolving MapApplicationService:" << e.what();
        auto viewModel = new MapViewModel(parent);
        logViewModelCreation("MapViewModel", true, QString("Demo mode - exception: %1").arg(e.what()));
        emit viewModelCreationFailed("MapViewModel", e.what());
        return viewModel;
    }
}

QObject* ViewModelFactory::createMapViewModel(
    application::MapApplicationService* mapAppService, 
    QObject* parent)
{
    if (!mapAppService) {
        qWarning() << "ViewModelFactory: MapApplicationService is null, creating demo MapViewModel";
        auto viewModel = new MapViewModel(parent);
        logViewModelCreation("MapViewModel", true, "Demo mode - null service");
        return viewModel;
    }

    qDebug() << "ViewModelFactory: Creating MapViewModel with injected service";
    auto viewModel = new MapViewModel(mapAppService, parent);
    logViewModelCreation("MapViewModel", true);
    emit viewModelCreated("MapViewModel");
    return viewModel;
}

QObject* ViewModelFactory::createDashboardViewModel(QObject* parent)
{
    qDebug() << "ViewModelFactory: Creating DashboardViewModel";

    try {
        auto viewModel = new DashboardViewModel(parent);
        logViewModelCreation("DashboardViewModel", true);
        emit viewModelCreated("DashboardViewModel");
        return viewModel;
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception creating DashboardViewModel:" << e.what();
        logViewModelCreation("DashboardViewModel", false, e.what());
        emit viewModelCreationFailed("DashboardViewModel", e.what());
        return nullptr;
    }
}

QObject* ViewModelFactory::createVehicleViewModel(QObject* parent)
{
    if (!m_serviceContainer) {
        qWarning() << "ViewModelFactory: No service container available, creating demo VehicleViewModel";
        auto viewModel = new presentation::viewmodels::VehicleViewModel(parent);
        logViewModelCreation("VehicleViewModel", true, "Demo mode - no service container");
        return viewModel;
    }

    try {
        // 从服务容器解析VehicleService
        auto vehicleService = m_serviceContainer->resolve<application::vehicle::VehicleService>();
        if (vehicleService) {
            qDebug() << "ViewModelFactory: Successfully resolved VehicleService, creating injected VehicleViewModel";
            auto viewModel = new presentation::viewmodels::VehicleViewModel(vehicleService.get(), parent);
            logViewModelCreation("VehicleViewModel", true);
            emit viewModelCreated("VehicleViewModel");
            return viewModel;
        } else {
            qWarning() << "ViewModelFactory: Failed to resolve VehicleService, creating demo VehicleViewModel";
            auto viewModel = new presentation::viewmodels::VehicleViewModel(parent);
            logViewModelCreation("VehicleViewModel", true, "Demo mode - service resolution failed");
            return viewModel;
        }
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception resolving VehicleService:" << e.what();
        auto viewModel = new presentation::viewmodels::VehicleViewModel(parent);
        logViewModelCreation("VehicleViewModel", true, QString("Demo mode - exception: %1").arg(e.what()));
        emit viewModelCreationFailed("VehicleViewModel", e.what());
        return viewModel;
    }
}

QObject* ViewModelFactory::createVehicleViewModel(
    application::vehicle::VehicleService* vehicleService,
    QObject* parent)
{
    if (!vehicleService) {
        qWarning() << "ViewModelFactory: VehicleService is null, creating demo VehicleViewModel";
        auto viewModel = new presentation::viewmodels::VehicleViewModel(parent);
        logViewModelCreation("VehicleViewModel", true, "Demo mode - null service");
        return viewModel;
    }

    qDebug() << "ViewModelFactory: Creating VehicleViewModel with injected service";
    auto viewModel = new presentation::viewmodels::VehicleViewModel(vehicleService, parent);
    logViewModelCreation("VehicleViewModel", true);
    emit viewModelCreated("VehicleViewModel");
    return viewModel;
}

QObject* ViewModelFactory::createTaskViewModel(QObject* parent)
{
    if (!m_serviceContainer) {
        qWarning() << "ViewModelFactory: No service container available, cannot create TaskViewModel";
        logViewModelCreation("TaskViewModel", false, "No service container");
        return nullptr;
    }

    try {
        // 从服务容器解析TaskService
        auto taskService = m_serviceContainer->resolve<application::task::TaskService>();
        if (taskService) {
            qDebug() << "ViewModelFactory: Successfully resolved TaskService, creating injected TaskViewModel";
            auto viewModel = new presentation::viewmodels::TaskViewModel(taskService, parent);
            logViewModelCreation("TaskViewModel", true);
            emit viewModelCreated("TaskViewModel");
            return viewModel;
        } else {
            qWarning() << "ViewModelFactory: Failed to resolve TaskService";
            logViewModelCreation("TaskViewModel", false, "Service resolution failed");
            return nullptr;
        }
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception resolving TaskService:" << e.what();
        logViewModelCreation("TaskViewModel", false, QString("Exception: %1").arg(e.what()));
        emit viewModelCreationFailed("TaskViewModel", e.what());
        return nullptr;
    }
}

QObject* ViewModelFactory::createTaskViewModel(
    application::task::TaskService* taskService,
    QObject* parent)
{
    if (!taskService) {
        qWarning() << "ViewModelFactory: TaskService is null";
        logViewModelCreation("TaskViewModel", false, "Null service");
        return nullptr;
    }

    qDebug() << "ViewModelFactory: Creating TaskViewModel with injected service";
    auto viewModel = new presentation::viewmodels::TaskViewModel(taskService, parent);
    logViewModelCreation("TaskViewModel", true);
    emit viewModelCreated("TaskViewModel");
    return viewModel;
}

QObject* ViewModelFactory::createResourceViewModel(QObject* parent)
{
    qDebug() << "ViewModelFactory: Creating ResourceViewModel";

    std::shared_ptr<application::MapApplicationService> mapAppService;
    if (m_serviceContainer) {
        try {
            mapAppService = m_serviceContainer->resolve<application::MapApplicationService>();
        } catch (const std::exception& e) {
            qWarning() << "ViewModelFactory: Exception resolving MapApplicationService for ResourceViewModel:" << e.what();
            emit viewModelCreationFailed("ResourceViewModel", e.what());
        }
    } else {
        qWarning() << "ViewModelFactory: Service container unavailable, ResourceViewModel will use null map service";
    }

    auto viewModel = new presentation::viewmodels::ResourceViewModel(mapAppService, parent);
    logViewModelCreation("ResourceViewModel", true);
    emit viewModelCreated("ResourceViewModel");
    return viewModel;
}

QObject* ViewModelFactory::createSimulatorViewModel(QObject* parent)
{
    if (!m_serviceContainer) {
        qWarning() << "ViewModelFactory: No service container available, cannot create SimulatorViewModel";
        logViewModelCreation("SimulatorViewModel", false, "No service container");
        return nullptr;
    }

    try {
        // 从服务容器解析所需的服务
        auto simulationService = m_serviceContainer->resolve<application::simulation::SimulationService>();
        auto vehicleService = m_serviceContainer->resolve<application::vehicle::VehicleService>();
        auto taskService = m_serviceContainer->resolve<application::task::TaskService>();

        if (!simulationService) {
            qWarning() << "ViewModelFactory: Failed to resolve SimulationService";
            logViewModelCreation("SimulatorViewModel", false, "SimulationService resolution failed");
            return nullptr;
        }

        // VehicleService 和 TaskService 可选，但至少需要 SimulationService
        auto viewModel = new presentation::viewmodels::SimulatorViewModel(
            simulationService,
            vehicleService ? vehicleService.get() : nullptr,
            taskService ? taskService.get() : nullptr,
            parent
        );

        logViewModelCreation("SimulatorViewModel", true);
        emit viewModelCreated("SimulatorViewModel");
        return viewModel;

    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception creating SimulatorViewModel:" << e.what();
        logViewModelCreation("SimulatorViewModel", false, QString("Exception: %1").arg(e.what()));
        emit viewModelCreationFailed("SimulatorViewModel", e.what());
        return nullptr;
    }
}

QObject* ViewModelFactory::createLogViewModel(QObject* parent)
{
    qDebug() << "ViewModelFactory: Creating LogViewModel";

    try {
        auto viewModel = new presentation::viewmodels::LogViewModel(parent);
        viewModel->initialize();
        logViewModelCreation("LogViewModel", true);
        emit viewModelCreated("LogViewModel");
        return viewModel;
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception creating LogViewModel:" << e.what();
        logViewModelCreation("LogViewModel", false, QString("Exception: %1").arg(e.what()));
        emit viewModelCreationFailed("LogViewModel", e.what());
        return nullptr;
    }
}


bool ViewModelFactory::isServiceContainerAvailable() const
{
    return m_serviceContainer != nullptr;
}

std::shared_ptr<infrastructure::ServiceContainer> ViewModelFactory::getServiceContainer() const
{
    return m_serviceContainer;
}

template<typename ViewModelType>
ViewModelType* ViewModelFactory::createViewModel(QObject* parent)
{
    static_assert(std::is_base_of_v<QObject, ViewModelType>, 
                  "ViewModelType must inherit from QObject");
    
    const QString typeName = ViewModelType::staticMetaObject.className();
    
    try {
        if (!m_serviceContainer) {
            qWarning() << "ViewModelFactory: No service container available for" << typeName;
            logViewModelCreation(typeName, false, "No service container");
            emit viewModelCreationFailed(typeName, "No service container");
            return nullptr;
        }

        // 这里可以根据不同的ViewModel类型进行特定的服务注入
        if constexpr (std::is_same_v<ViewModelType, MapViewModel>) {
            return createMapViewModel(parent);
        } else if constexpr (std::is_same_v<ViewModelType, DashboardViewModel>) {
            return createDashboardViewModel(parent);
        } else {
            qWarning() << "ViewModelFactory: Unsupported ViewModel type:" << typeName;
            logViewModelCreation(typeName, false, "Unsupported type");
            emit viewModelCreationFailed(typeName, "Unsupported ViewModel type");
            return nullptr;
        }
    } catch (const std::exception& e) {
        qWarning() << "ViewModelFactory: Exception creating" << typeName << ":" << e.what();
        logViewModelCreation(typeName, false, e.what());
        emit viewModelCreationFailed(typeName, e.what());
        return nullptr;
    }
}

void ViewModelFactory::logViewModelCreation(const QString& type, bool success, const QString& error)
{
    if (success) {
        if (error.isEmpty()) {
            qDebug() << "ViewModelFactory: Successfully created" << type;
        } else {
            qDebug() << "ViewModelFactory: Created" << type << "in demo mode:" << error;
        }
    } else {
        qWarning() << "ViewModelFactory: Failed to create" << type << ":" << error;
    }
}

} // namespace factories
} // namespace presentation
